package com.example.auth.demo.service;

import com.example.auth.demo.domain.PageResult;
import com.example.auth.demo.domain.ResultCode;
import com.example.auth.demo.domain.ResultJson;
import com.example.auth.demo.domain.auth.ResponseUserToken;
import com.example.auth.demo.domain.auth.Role;
import com.example.auth.demo.domain.auth.UserDetail;
import com.example.auth.demo.exception.CustomException;
import com.example.auth.demo.mapper.AuthMapper;
import com.example.auth.demo.utils.JwtUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.example.auth.demo.domain.auth.Equipment;
import com.example.auth.demo.domain.auth.Task;

import com.example.auth.demo.domain.auth.Player;
import com.example.auth.demo.domain.auth.PlayerFeedback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.example.auth.demo.domain.auth.EquipmentPrice;
import com.example.auth.demo.domain.auth.PlayerWallet;




import com.example.auth.demo.domain.auth.Guild;
import com.example.auth.demo.domain.auth.GuildActivity;
import com.example.auth.demo.domain.auth.GuildActivityParticipant;
import com.example.auth.demo.domain.auth.GuildChat;
import com.example.auth.demo.domain.auth.GuildContribution;
import com.example.auth.demo.domain.auth.GuildDiplomacy;
import com.example.auth.demo.domain.auth.GuildMember;
import com.example.auth.demo.domain.auth.GuildNotice;


import java.util.*;


@Service
public class AuthServiceImpl implements AuthService {
    private final AuthenticationManager authenticationManager;
    private final UserDetailsService userDetailsService;
    private final JwtUtils jwtTokenUtil;
    private final AuthMapper authMapper;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    public AuthServiceImpl(AuthenticationManager authenticationManager, @Qualifier("CustomUserDetailsService") UserDetailsService userDetailsService, JwtUtils jwtTokenUtil, AuthMapper authMapper) {
        this.authenticationManager = authenticationManager;
        this.userDetailsService = userDetailsService;
        this.jwtTokenUtil = jwtTokenUtil;
        this.authMapper = authMapper;
    }


    @Override
    public List<UserDetail> getAllUsers() {
        return authMapper.findAllUsers();
    }

    @Override
    public PageResult<UserDetail> getAllUsersByPage(int page, int pageSize) {
        int offset = (page - 1) * pageSize;
        List<UserDetail> records = authMapper.findAllUsersByPage(pageSize, offset);
        int total = authMapper.countAllUsers();

        return PageResult.<UserDetail>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }
    @Override
    public UserDetail register(UserDetail userDetail) {
        final String username = userDetail.getUsername();
        if(authMapper.findByUsername(username)!=null) {
            throw new CustomException(ResultJson.failure(ResultCode.BAD_REQUEST, "用户已存在"));
        }
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String rawPassword = userDetail.getPassword();
        userDetail.setPassword(encoder.encode(rawPassword));
        userDetail.setLastPasswordResetDate(new Date());
        authMapper.insert(userDetail);
        long roleId = userDetail.getRole().getId();
        Role role = authMapper.findRoleById(roleId);
        userDetail.setRole(role);
        authMapper.insertRole(userDetail.getId(), roleId);
        return userDetail;
    }

    @Override
    public ResponseUserToken login(String username, String password) {
        //用户验证
        final Authentication authentication = authenticate(username, password);
        //存储认证信息
        SecurityContextHolder.getContext().setAuthentication(authentication);
        //生成token
        final UserDetail userDetail = (UserDetail) authentication.getPrincipal();
        final String token = jwtTokenUtil.generateAccessToken(userDetail);
        //存储token
        jwtTokenUtil.putToken(username, token);
        return new ResponseUserToken(token, userDetail);
    }

    @Override
    public void logout(String token) {
        token = token.substring(tokenHead.length());
        String userName = jwtTokenUtil.getUsernameFromToken(token);
        jwtTokenUtil.deleteToken(userName);
    }

    @Override
    public ResponseUserToken refresh(String oldToken) {
        String token = oldToken.substring(tokenHead.length());
        String username = jwtTokenUtil.getUsernameFromToken(token);
        UserDetail userDetail = (UserDetail) userDetailsService.loadUserByUsername(username);
        if (jwtTokenUtil.canTokenBeRefreshed(token, userDetail.getLastPasswordResetDate())){
            token =  jwtTokenUtil.refreshToken(token);
            return new ResponseUserToken(token, userDetail);
        }
        return null;
    }

    @Override
    public UserDetail getUserByToken(String token) {
        token = token.substring(tokenHead.length());
        return jwtTokenUtil.getUserFromToken(token);
    }



    @Override
    public void createRole(Role role) {
        authMapper.insertRoleInfo(role);
    }

    @Override
    public void updateRole(Role role) {
        try {
            authMapper.updateRoleInfo(role);
        } catch (Exception e) {
            // 记录详细的错误日志
            e.printStackTrace();
            // 抛出自定义异常，返回更友好的错误信息给客户端
            throw new CustomException(ResultJson.failure(ResultCode.SERVER_ERROR, "角色信息更新失败"));
        }
    }

    @Override
    public void deleteRole(long roleId) {
        authMapper.deleteRole(roleId);
    }

    @Override
    public PageResult<Role> getAllRoles(int page, int pageSize) {
        int offset = (page - 1) * pageSize;
        List<Role> records = authMapper.getAllRolesByPage(pageSize, offset);
        int total = authMapper.countAllRoles();

        return PageResult.<Role>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }

    @Override
    public void createEquipment(Equipment equipment) {
        authMapper.insertEquipment(equipment);
    }

    @Override
    public void addEquipmentToRole(long roleId, long equipmentId) {
        authMapper.addEquipmentToRole(roleId, equipmentId);
        // 这里可以添加更新角色属性的逻辑
        updateRoleAttributes(roleId);
    }

    @Override
    public void removeEquipmentFromRole(long roleId, long equipmentId) {
        authMapper.removeEquipmentFromRole(roleId, equipmentId);
        // 这里可以添加更新角色属性的逻辑
        updateRoleAttributes(roleId);
    }

    @Override
    public List<Equipment> getRoleEquipments(long roleId) {
        return authMapper.getRoleEquipments(roleId);
    }

    @Override
    public Equipment getEquipmentById(long equipmentId) {
        return authMapper.getEquipmentById(equipmentId);
    }
    @Override
    public PageResult<Equipment> getAllEquipments(int page, int pageSize) {
        int offset = (page - 1) * pageSize;
        List<Equipment> records = authMapper.getAllEquipmentsByPage(pageSize, offset);
        int total = authMapper.countAllEquipments();

        return PageResult.<Equipment>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }
    @Override
    public void updateEquipment(Equipment equipment) {
        authMapper.updateEquipment(equipment);
    }



    @Override
    public void createTask(Task task) {
        authMapper.insertTask(task);
    }

    @Override
    public void assignTaskToRole(long roleId, long taskId) {
        authMapper.assignTaskToRole(roleId, taskId);
    }

    @Override
    public void markTaskAsCompleted(long roleId, long taskId) {
        authMapper.markTaskAsCompleted(roleId, taskId);
    }

    @Override
    public List<Task> getRoleTasks(long roleId) {
        return authMapper.getRoleTasks(roleId);
    }

    @Override
    public List<Task> getIncompleteRoleTasks(long roleId) {
        return authMapper.getIncompleteRoleTasks(roleId);
    }

    @Override
    public List<Task> getCompletedRoleTasks(long roleId) {
        return authMapper.getCompletedRoleTasks(roleId);
    }

    @Override
    public Task getTaskById(long taskId) {
        return authMapper.getTaskById(taskId);
    }

    @Override
    public PageResult<Task> getAllTasks(int page, int pageSize) {
        // 计算SQL查询的偏移量
        int offset = (page - 1) * pageSize;

        // 查询当前页数据
        List<Task> records = authMapper.getAllTasksByPage(pageSize, offset);

        // 查询总记录数
        int total = authMapper.countAllTasks();

        // 构建分页结果对象
        return PageResult.<Task>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }

    @Override
    public List<Task> getIncompleteTasksByUserId(Long userId) {
        return authMapper.getIncompleteTasksByUserId(userId);
    }

    @Override
    public List<Task> getCompletedTasksByUserId(Long userId) {
        return authMapper.getCompletedTasksByUserId(userId);
    }
//玩家管理
@Override
public void createPlayer(Player player) {
    authMapper.insertPlayer(player);
}

    @Override
    public Player getPlayerByAccount(String account) {
        return authMapper.getPlayerByAccount(account);
    }

    @Override
    public Player getPlayerById(Long playerId) {
        return authMapper.getPlayerById(playerId);
    }

    @Override
    public void updatePlayer(Player player) {
        authMapper.updatePlayer(player);
    }

    @Override
    public void createPlayerFeedback(PlayerFeedback feedback) {
        authMapper.insertPlayerFeedback(feedback);
    }

    @Override
    public List<PlayerFeedback> getPlayerFeedbacks(Long playerId) {
        return authMapper.getPlayerFeedbacks(playerId);
    }

    @Override
    public PageResult<PlayerFeedback> getUnprocessedFeedbacks(int page, int pageSize) {
        // 计算分页偏移量
        int offset = (page - 1) * pageSize;

        // 构建分页查询参数
        Map<String, Object> params = new HashMap<>();
        params.put("offset", offset);
        params.put("pageSize", pageSize);

        // 查询分页数据
        List<PlayerFeedback> records = authMapper.getUnprocessedFeedbacksByPage(params);

        // 查询总记录数
        int total = authMapper.countUnprocessedFeedbacks();

        // 构建分页结果
        return PageResult.<PlayerFeedback>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }
    @Override
    public void markFeedbackAsProcessed(Long feedbackId) {
        authMapper.markFeedbackAsProcessed(feedbackId);
    }


    @Override
    public PageResult<Player> getPlayerList(int page, int pageSize, String keyword) {
        int offset = (page - 1) * pageSize;

        // 构建查询条件
        Map<String, Object> params = new HashMap<>();
        params.put("keyword", keyword);
        params.put("offset", offset);
        params.put("pageSize", pageSize);

        List<Player> records = authMapper.getPlayerListByPage(params);
        int total = authMapper.countPlayerList(params);

        return PageResult.<Player>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }

    @Override
    public void deletePlayer(Long id) {
        authMapper.deletePlayer(id);
    }




    // 公会表相关
    @Override
    public void createGuild(Guild guild) {
        authMapper.insertGuild(guild);
    }

    @Override
    public Guild getGuildById(Long guildId) {
        return authMapper.getGuildById(guildId);
    }

    @Override
    public List<Guild> getAllGuilds() {
        return authMapper.getAllGuilds();
    }

    @Override
    public void updateGuild(Guild guild) {
        authMapper.updateGuild(guild);
    }

    @Override
    public void deleteGuild(Long guildId) {
        authMapper.deleteGuild(guildId);
    }


    @Override
    public PageResult<Guild> getGuildsByPage(int page, int pageSize, String sortField, String sortOrder) {
        int offset = (page - 1) * pageSize;
        List<Guild> records = authMapper.getGuildsByPage(offset, pageSize, sortField, sortOrder);
        int total = authMapper.countAllGuilds();

        return PageResult.<Guild>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }
    // 公会成员表相关
    @Override
    public void addGuildMember(GuildMember member) {
        authMapper.insertGuildMember(member);
    }

    @Override
    public GuildMember getGuildMemberById(Long memberId) {
        return authMapper.getGuildMemberById(memberId);
    }

    @Override
    public List<GuildMember> getGuildMembersByGuildId(Long guildId) {
        return authMapper.getGuildMembersByGuildId(guildId);
    }

    @Override
    public void updateGuildMember(GuildMember member) {
        authMapper.updateGuildMember(member);
    }

    @Override
    public void deleteGuildMember(Long memberId) {
        authMapper.deleteGuildMember(memberId);
    }

    @Override
    public void approveGuildMember(Long memberId) {
        GuildMember member = getGuildMemberById(memberId);
        if (member != null) {
            member.setIsApproved(1);
            updateGuildMember(member);
        }
    }
    @Override
    public PageResult<GuildMember> getAllGuildMembers(int page, int pageSize) {
        int offset = (page - 1) * pageSize;
        System.out.println("计算得到的偏移量offset: " + offset);
        System.out.println("每页数量pageSize: " + pageSize);
        // 从数据库获取当前页的公会成员列表
        List<GuildMember> records = authMapper.getAllGuildMembers(offset, pageSize);
        // 获取公会成员总数
        int total = authMapper.countAllGuildMembers();

        return PageResult.<GuildMember>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }
    // 公会公告表相关
    @Override
    public void publishGuildNotice(GuildNotice notice) {
        authMapper.insertGuildNotice(notice);
    }

    @Override
    public GuildNotice getGuildNoticeById(Long noticeId) {
        return authMapper.getGuildNoticeById(noticeId);
    }

    @Override
    public List<GuildNotice> getGuildNoticesByGuildId(Long guildId) {
        return authMapper.getGuildNoticesByGuildId(guildId);
    }

    @Override
    public void updateGuildNotice(GuildNotice notice) {
        authMapper.updateGuildNotice(notice);
    }

    @Override
    public void deleteGuildNotice(Long noticeId) {
        authMapper.deleteGuildNotice(noticeId);
    }


    @Override
    public PageResult<GuildNotice> getAllGuildNotices(int page, int pageSize) {
        int offset = (page - 1) * pageSize;
        // 从数据库获取当前页的公会公告列表
        List<GuildNotice> records = authMapper.getAllGuildNotices(offset, pageSize);
        // 获取公会公告总数
        int total = authMapper.countAllGuildNotices();

        return PageResult.<GuildNotice>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }
    // 公会活动表相关
    @Override
    public void createGuildActivity(GuildActivity activity) {
        authMapper.insertGuildActivity(activity);
    }

    @Override
    public GuildActivity getGuildActivityById(Long activityId) {
        return authMapper.getGuildActivityById(activityId);
    }

    @Override
    public List<GuildActivity> getGuildActivitiesByGuildId(Long guildId) {
        return authMapper.getGuildActivitiesByGuildId(guildId);
    }

    @Override
    public void updateGuildActivity(GuildActivity activity) {
        authMapper.updateGuildActivity(activity);
    }

    @Override
    public void deleteGuildActivity(Long activityId) {
        authMapper.deleteGuildActivity(activityId);
    }

    @Override
    public PageResult<GuildActivity> getAllGuildActivities(int page, int pageSize) {
        int offset = (page - 1) * pageSize;
        // 从数据库获取当前页的公会活动列表
        List<GuildActivity> records = authMapper.getAllGuildActivities(offset, pageSize);
        // 获取公会活动总数
        int total = authMapper.countAllGuildActivities();

        return PageResult.<GuildActivity>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }
    // 公会活动参与表相关
    @Override
    public void addActivityParticipant(GuildActivityParticipant participant) {
        authMapper.insertGuildActivityParticipant(participant);
    }

    @Override
    public List<GuildActivityParticipant> getParticipantsByActivityId(Long activityId) {
        return authMapper.getParticipantsByActivityId(activityId);
    }

    @Override
    public void removeActivityParticipant(Long participantId) {
        authMapper.deleteGuildActivityParticipant(participantId);
    }
    // 在AuthServiceImpl类中添加
    @Override
    public List<GuildActivityParticipant> getAllActivityParticipants() {
        return authMapper.getAllActivityParticipants();
    }

    // 公会贡献表相关
    @Override
    public void recordGuildContribution(GuildContribution contribution) {
        authMapper.insertGuildContribution(contribution);
    }

    @Override
    public List<GuildContribution> getContributionsByPlayerId(Long playerId) {
        return authMapper.getContributionsByPlayerId(playerId);
    }

    @Override
    public List<GuildContribution> getContributionsByGuildId(Long guildId) {
        return authMapper.getContributionsByGuildId(guildId);
    }

    @Override
    public void updateGuildContribution(GuildContribution contribution) {
        authMapper.updateGuildContribution(contribution);
    }

    @Override
    public PageResult<GuildContribution> getAllGuildContributions(Integer page, Integer pageSize, String sort, String order) {
        // 校验排序字段合法性
        if (!Arrays.asList("recordTime", "contribution").contains(sort)) {
            sort = "recordTime"; // 默认按记录时间排序
        }

        // 校验排序方向合法性
        if (!Arrays.asList("asc", "desc").contains(order)) {
            order = "desc"; // 默认降序
        }

        // 计算偏移量
        int offset = (page - 1) * pageSize;

        // 构造排序字符串
        String orderBy = String.format("%s %s",
                convertFieldToColumn(sort), // 字段名转列名
                order);

        // 查询当前页记录
        List<GuildContribution> contributions = authMapper.getAllGuildContributions(offset, pageSize, orderBy);

        // 获取总记录数
        int total = authMapper.countAllGuildContributions();

        // 构建分页结果
        return PageResult.<GuildContribution>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(contributions)
                .build();
    }

    // 辅助方法：将Java字段名转换为数据库列名
    private String convertFieldToColumn(String field) {
        if ("recordTime".equals(field)) return "record_time";
        if ("contribution".equals(field)) return "contribution";
        return "record_time"; // 默认返回记录时间
    }
    // 公会外交关系表相关
    @Override
    public void establishDiplomacy(GuildDiplomacy diplomacy) {
        authMapper.insertGuildDiplomacy(diplomacy);
    }

    @Override
    public GuildDiplomacy getGuildDiplomacyById(Long diplomacyId) {
        return authMapper.getGuildDiplomacyById(diplomacyId);
    }

    @Override
    public List<GuildDiplomacy> getDiplomaciesByGuildId(Long guildId) {
        return authMapper.getDiplomaciesByGuildId(guildId);
    }

    @Override
    public void updateGuildDiplomacy(GuildDiplomacy diplomacy) {
        authMapper.updateGuildDiplomacy(diplomacy);
    }

    @Override
    public void terminateDiplomacy(Long diplomacyId) {
        authMapper.deleteGuildDiplomacy(diplomacyId);
    }

    @Override
    public PageResult<GuildDiplomacy> getAllDiplomacies(int page, int pageSize, String sort, String order) {
        // 验证分页参数
        if (page <= 0) page = 1;
        if (pageSize <= 0 || pageSize > 100) pageSize = 10;

        // 验证排序字段（转为小写进行校验）
        List<String> validSorts = Arrays.asList("id", "guild_id", "other_guild_id", "relation_type", "relation_time");
        String normalizedSort = sort.toLowerCase();
        if (!validSorts.contains(normalizedSort)) {
            normalizedSort = "id";
        }

        // 验证排序方向（转为小写进行校验）
        String normalizedOrder = order.toLowerCase();
        if (!"asc".equals(normalizedOrder) && !"desc".equals(normalizedOrder)) {
            normalizedOrder = "desc";
        }

        // 计算偏移量（手动分页，替代PageHelper）
        int offset = (page - 1) * pageSize;

        // 构建排序SQL片段
        String orderBy = normalizedSort + " " + normalizedOrder;

        // 查询当前页数据
        List<GuildDiplomacy> records = authMapper.getAllDiplomaciesByPage(offset, pageSize, orderBy);

        // 查询总记录数
        int total = authMapper.countAllDiplomacies();

        // 构建分页结果
        return PageResult.<GuildDiplomacy>builder()
                .page(page)
                .rows(pageSize)
                .total(total)
                .records(records)
                .build();
    }
    // 公会聊天表相关
    @Override
    public void sendGuildChat(GuildChat chat) {
        authMapper.insertGuildChat(chat);
    }

    @Override
    public List<GuildChat> getChatsByGuildId(Long guildId) {
        return authMapper.getChatsByGuildId(guildId);
    }

    private void updateRoleAttributes(long roleId) {
        List<Equipment> equipments = getRoleEquipments(roleId);
        Role role = authMapper.findRoleById(roleId);
        // 这里可以根据装备的属性修改器更新角色的初始属性
        // 示例代码，实际需要根据具体业务逻辑实现
        StringBuilder newAttributes = new StringBuilder(role.getInitialAttributes());
        for (Equipment equipment : equipments) {
            newAttributes.append(equipment.getAttributeModifier());
        }
        role.setInitialAttributes(newAttributes.toString());
        authMapper.updateRoleInfo(role);
    }


    private Authentication authenticate(String username, String password) {
        try {
            //该方法会去调用userDetailsService.loadUserByUsername()去验证用户名和密码，如果正确，则存储该用户名密码到“security 的 context中”
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException | BadCredentialsException e) {
            throw new CustomException(ResultJson.failure(ResultCode.LOGIN_ERROR, e.getMessage()));
        }
    }
}